import pyautogui as pag
import ctypes
import time
from multiprocessing import Process,Queue
import random

SendInput = ctypes.windll.user32.SendInput

W = 0x11
A = 0x1E
S = 0x1F
D = 0x20
ESC = 0x1B
NP_2 = 0x50
NP_4 = 0x4B
NP_6 = 0x4D
NP_8 = 0x48

# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time",ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]

# Actuals Functions

def pressKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def releaseKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def movetowindow():
    pag.moveTo(300,200)
    pag.click()
    print('clicked')
    time.sleep(0.2)

def turn_left():
    pressKey(A)
    pressKey(W)
    time.sleep(0.2)
    releaseKey(A)
    releaseKey(W)
def turn_right():
    pressKey(D)
    pressKey(W)
    time.sleep(0.2)
    releaseKey(D)
    releaseKey(W)
def forward():
    pressKey(W)
    time.sleep(1)
    releaseKey(W)

def get_window_pisition():
    while True:
        print(pag.position())
        time.sleep(0.01)


def direct_choice(queue):
    while True:
        func = queue.get()
        print(f'execute {func}')
        eval(func)()
        time.sleep(0.1)
        if queue.empty():
            print('all executed')
            forward()
            # break


def direct_execute(func='forward'):
    eval(func)()

def generate_direction(direction_list,queue):
    while True:
        idx = random.randint(0,2)
        func = direction_list[idx]
        print(f'generaetd {func}')
        queue.put(func)
        time.sleep(0.2)
        if queue.full():
            print('all generated')
            # break
if __name__ == '__main__':
    direction_list = ['forward', 'turn_left', 'turn_right']
    direction_temp = Queue(maxsize=10)
    for i in range(3)[::-1]:
        print(i+1)
        time.sleep(1)
    movetowindow()

    direct_execute('forward')

    direct_execute('turn_left')
    direct_execute('forward')

    direct_execute('turn_right')
    direct_execute('forward')

    p1 = Process(target=generate_direction,args=(direction_list,direction_temp))
    p2 = Process(target=direct_choice,args=(direction_temp,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    pass